#coding:utf8
#
# Author: CMGS
# Created on 2010-9-26
#

import time
from common import config as _config
from common import defcode as _defcode
from libs.rpc import rpc as _rpc
from libs.debugger import Debugger as _debugger
from libs.session import sessionPool as _sessionPool

def autoCleaner(hash):
    sessions = _sessionPool.getSessions(hash)
    
    if sessions is None:
        return
    
    for sid in sessions.keys():
        if sid in _config.UNSID_KEY:
            continue

        last = sessions[sid][_config.USER_TIME_NAME]
        now = time.time()
        if now - last > _config.AUTO_REFRESH_TIME:
            from appjoin import apijoin
            apijoin.closeJoin(hash, sid)

def keepOnline(hash, sid):
    session = _sessionPool.getSession(hash, sid)

    if session is None:
        return _rpc.toJson({'code': _defcode.OPT_FAILED, 'reason': 'no session'})
    
    session[_config.USER_TIME_NAME] = time.time()
    
    return _rpc.toJson({'code': _defcode.OPT_OK})

def updateVector(hash, sid, v):
    sessions = _sessionPool.getSessions(hash)
    try:
        v = _rpc.loadJson(v)
    except Exception, e:
        _debugger.exc(e)
        return _rpc.toJson({'code': _defcode.OPT_FAILED, 'reason': 'not json'}) 
    # check user permission
    if sessions is None:
        return _rpc.toJson({'code': _defcode.OPT_FAILED, 'reason': 'not open file'})
    checked = _checkUser(sessions, sid)
    if checked is not True:
        return checked

    print v
    for sid in sessions.keys():
        if sid in _config.UNSID_KEY:
            continue
        # no and v are int, json maybe convert them to str
        try:
            no = sessions[sid][_config.MODIFY_NO_NAME]
            sessions[sid][_config.MODIFY_VECTOR_NAME] = int(v[str(no)])
        except Exception, e:
            _debugger.exc(e)

    # clean old msg
    _cleanMsgList(sessions, v)
    return _rpc.toJson({'code': _defcode.OPT_OK})

def kickUser(hash, sid, username):
    sessions = _sessionPool.getSessions(hash)
    checked = _checkUser(sessions, sid)
    if checked is not True:
        return checked

    from appjoin import apijoin
    return apijoin.closeJoin(hash, _getKickTarget(sessions, username))

def _cleanMsgList(sessions, v):
    p = 0
    length = len(sessions[_config.MEM_MODIFIES_NAME])
    while p < length:
        msg = sessions[_config.MEM_MODIFIES_NAME][p]
        try:
            no = str(msg[_config.MODIFY_NO_NAME])
            vec = int(v[no])            
            assert (vec > int(msg[_config.MODIFY_VECTOR_NAME][no]))
            sessions[_config.MEM_MODIFIES_NAME].remove(msg)
            p = 0
            length = len(sessions[_config.MEM_MODIFIES_NAME])
        except Exception, e:
            _debugger.exc(e)
            p += 1

def _getKickTarget(sessions, username):
    for sid in sessions.keys():
        if sid in _config.UNSID_KEY or sessions[sid]['username'] != username:
            continue
        return sid

def _checkUser(sessions, sid):
    if not sessions.has_key(sid):
        return _rpc.toJson({'code': _defcode.OPT_FAILED, 'reason': 'no session'})

    if sessions[sid][_config.MODIFY_NO_NAME] != 0:
        return _rpc.toJson({'code': _defcode.OPT_FAILED, 'reason': 'not owener'})
    
    return True
